package org.lop.modules.data.domain;

import java.io.Serializable;

import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;

/**
 * 重新定义getOffset()等.
 * 
 * 由于习惯不同, 将page的起始页由0调整为1.
 * 
 * @author 潘瑞峥
 * @date 2013-5-31
 */
public class PageableBean implements Pageable, Serializable {

	private static final long serialVersionUID = -4802414965823532636L;

	private int page;
	private int size;
	private Sort sort;

	public PageableBean() {
	}

	/**
	 * Creates a new {@link PageRequest}. Pages are zero indexed, thus providing 0 for {@code page}
	 * will return the first page.
	 * 
	 * @param size
	 * @param page
	 */
	public PageableBean( int page, int size ) {

		this( page, size, null );
	}

	/**
	 * Creates a new {@link PageableBean} with sort parameters applied.
	 * 
	 * @param page
	 * @param size
	 * @param direction
	 * @param properties
	 */
	public PageableBean( int page, int size, Direction direction, String... properties ) {

		this( page, size, new Sort( direction, properties ) );
	}

	/**
	 * Creates a new {@link PageableBean} with sort parameters applied.
	 * 
	 * @param page
	 * @param size
	 * @param sort
	 */
	public PageableBean( int page, int size, Sort sort ) {

		if ( 0 > page ) {
			throw new IllegalArgumentException( "Page index must not be less than zero!" );
		}

		if ( 0 >= size ) {
			throw new IllegalArgumentException( "Page size must not be less than or equal to zero!" );
		}

		this.page = page;
		this.size = size;
		this.sort = sort;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.springframework.data.domain.Pageable#getPageSize()
	 */
	public int getPageSize() {

		return size;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.springframework.data.domain.Pageable#getPageNumber()
	 */
	public int getPageNumber() {

		return page;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.springframework.data.domain.Pageable#getFirstItem()
	 */
	public int getOffset() {

		return ( page - 1 ) * size;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.springframework.data.domain.Pageable#getSort()
	 */
	public Sort getSort() {

		return sort;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see java.lang.Object#equals(java.lang.Object)
	 */
	@Override
	public boolean equals( final Object obj ) {

		if ( this == obj ) {
			return true;
		}

		if ( !( obj instanceof PageableBean ) ) {
			return false;
		}

		PageableBean that = ( PageableBean ) obj;

		boolean pageEqual = this.page == that.page;
		boolean sizeEqual = this.size == that.size;

		boolean sortEqual = this.sort == null ? that.sort == null : this.sort.equals( that.sort );

		return pageEqual && sizeEqual && sortEqual;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see java.lang.Object#hashCode()
	 */
	@Override
	public int hashCode() {

		int result = 17;

		result = 31 * result + page;
		result = 31 * result + size;
		result = 31 * result + ( null == sort ? 0 : sort.hashCode() );

		return result;
	}

	public int getPage() {
		return page;
	}

	public void setPage( int page ) {
		this.page = page;
	}

	public int getSize() {
		return size;
	}

	public void setSize( int size ) {
		this.size = size;
	}

	public void setSort( Sort sort ) {
		this.sort = sort;
	}

}